package Dm

import (
	"db2s/ETL"
	"db2s/global"
	"db2s/parDef"
	"db2s/ref"
	"fmt"
)

func (cm ColumnMe) Set(parameter string, value any) (err error) {
	return ref.UpdateStructJsonValue(cm, parameter, value)
}
func (cm ColumnMe) Result(object string) global.Return {
	switch object {
	default:
		return global.Return{}
	}
}
func (cm ColumnMe) Comment(parameter parDef.Parameter) (result global.Return, err error) {
	var event = "[Comment]"
	var execSql []string
	for _, v := range []string{"all_col_comments", "dba_col_comments"} {
		execSql = append(execSql, fmt.Sprintf("select "+
			"COLUMN_NAME as \"columnName\","+
			"to_char(comments ) AS \"columnComment\" "+
			"from %v "+
			"where "+
			"owner IN ( '%v' ) "+
			"and  "+
			"TABLE_NAME IN ( '%v' )",
			v,
			parameter.Object.Schema,
			parameter.Object.Table))
	}
	if result, err = forExecQuerySql(event, parameter, ETL.SMap, execSql); err != nil {
		err = ref.ErrAddPrintf("Comment", err)
		return
	}
	if result.Result == nil {
		return
	}
	var p = make(map[string]string)
	for _, vv := range result.Result.([]map[string]any) {
		pp := mapNullActive(vv)
		column, ok1 := pp["columnName"]
		comment, ok2 := pp["columnComment"]
		if ok1 && ok2 {
			p[fmt.Sprintf("%v", column)] = fmt.Sprintf("%v", comment)
		}
	}
	result.Result = p
	return
}
func (cm ColumnMe) LobMeta(parameter parDef.Parameter) (result global.Return, err error) {
	var event = "[LobMeta]"
	var execSql []string
	for _, v := range []string{"all_tab_columns", "dba_tab_columns"} {
		execSql = append(execSql, fmt.Sprintf("select "+
			"column_name as \"columnName\","+
			"data_type as \"columnType\" "+
			"from "+
			"%v "+
			"where OWNER = '%s' "+
			"AND TABLE_NAME = '%s' "+
			"AND data_type like '%%LOB%%'",
			v,
			parameter.Object.Schema,
			parameter.Object.Table))
	}
	if result, err = forExecQuerySql(event, parameter, ETL.SMap, execSql); err != nil {
		err = ref.ErrAddPrintf("LobMeta", err)
		return
	}
	if result.Result == nil {
		return
	}
	var p = make(map[string]string)
	for _, vv := range result.Result.([]map[string]any) {
		pp := mapNullActive(vv)
		column, ok1 := pp["columnName"]
		colType, ok2 := pp["columnType"]
		if ok1 && ok2 {
			p[fmt.Sprintf("%v", column)] = fmt.Sprintf("%v", colType)
		}
	}
	result.Result = p
	return
}
func (cm ColumnMe) BigVarcharMeta(parameter parDef.Parameter) (result global.Return, err error) {
	var event = "[BigVarcharMeta]"
	var execSql []string
	for _, v := range []string{"all_tab_columns", "dba_tab_columns"} {
		execSql = append(execSql, fmt.Sprintf("SELECT "+
			"COLUMN_NAME \"columnName\" ,"+
			"DATA_TYPE as \"columnType\","+
			"DATA_LENGTH as \"dataLength\" "+
			"FROM %v "+
			"WHERE "+
			"OWNER = '%s' "+
			"and table_name = '%s' "+
			"and DATA_TYPE = 'VARCHAR2' AND DATA_LENGTH >= %d",
			v,
			parameter.Object.Schema,
			parameter.Object.Table,
			1000))
	}
	if result, err = forExecQuerySql(event, parameter, ETL.SMap, execSql); err != nil {
		err = ref.ErrAddPrintf("BigVarcharMeta", err)
		return
	}
	if result.Result == nil {
		return
	}
	var p = make(map[string]string)
	for _, vv := range result.Result.([]map[string]any) {
		pp := mapNullActive(vv)
		column, ok1 := pp["columnName"]
		colType, ok2 := pp["columnType"]
		colLength, ok3 := pp["dataLength"]
		if ok1 && ok2 && ok3 {
			p[fmt.Sprintf("%v", column)] = fmt.Sprintf("%v(%v)", colType, colLength)
		}
	}
	result.Result = p
	return
}

func (cm ColumnMe) MapConversionMeta() {

}

func (cm ColumnMe) Meta(parameter parDef.Parameter) (result global.Return, err error) {
	var event = "[Meta]"
	var res []parDef.ColumnMeta
	var execSql []string
	var commentRes global.Return
	if commentRes, err = cm.Comment(parameter); err != nil {
		err = ref.ErrAddPrintf("Meta", err)
		return
	}
	for _, v := range []string{"all_tab_columns", "dba_tab_columns"} {
		execSql = append(execSql, fmt.Sprintf("SELECT "+
			"atc.owner AS \"databaseName\",\n\t"+
			"atc.TABLE_NAME AS \"tableName\",\n\t"+
			"atc.column_name AS \"columnName\",\n\t"+
			"atc.data_type AS \"dataType\",\n\t"+
			"atc.DATA_PRECISION AS \"dataPrecision\",\n\t"+
			"atc.DATA_SCALE AS \"dataScale\",\n\t"+
			"atc.DATA_LENGTH AS \"dataLength\",\n\t"+
			"atc.char_length AS \"charLength\",\n\t"+
			"atc.COLUMN_id AS \"columnSeq\",\n\t"+
			"atc.NULLABLE AS \"isNull\",\n\t"+
			"'' AS \"charset\",\n\t"+
			"'' AS \"collationName\",\n\t"+
			"atc.DATA_DEFAULT AS \"columnDefault\" \n"+
			"FROM\n\t"+
			"%v atc\n"+
			"WHERE\n\t"+
			"atc.owner IN ( '%v' ) \n\t"+
			"AND atc.TABLE_NAME IN ( '%v' ) \n"+
			"ORDER BY\n\t"+
			"atc.column_id",
			v, parameter.Object.Schema, parameter.Object.Table))
	}
	if result, err = forExecQuerySql(event, parameter, ETL.SMap, execSql); err != nil {
		err = ref.ErrAddPrintf("Meta", err)
		return
	}
	if result.Result == nil {
		return
	}
	var mapValueNull []map[string]any
	for _, v := range result.Result.([]map[string]interface{}) {
		var vv = mapNullActive(v)
		if column, ok := vv["columnName"]; ok && commentRes.Result != nil {
			if val, ok1 := commentRes.Result.(map[string]string)[fmt.Sprintf("%v", column)]; ok1 {
				vv["columnComment"] = val
			}
		}
		for _, length := range []string{"dataLength", "charLength", "dataPrecision", "dataScale"} {
			if charLength, ok := vv[length]; ok {
				var carl int64
				if carl, err = stringAnyToInt64(charLength); err != nil {
					err = ref.ErrAddPrintf("Meta", err)
					return
				}
				vv[length] = carl
			}
		}
		vv["columnType"] = ExtractTypeName(fmt.Sprintf("%v", vv["dataType"]))
		mapValueNull = append(mapValueNull, vv)
		var dd = parDef.ColumnMeta{}
		if err = mapStringToStruct(vv, &dd); err != nil {
			err = ref.ErrAddPrintf("Meta", err)
			return
		}
		res = append(res, dd)
	}
	result.Result = res
	return
}
